#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ==================================================
# @File    : base_run
# @IDE     : PyCharm
# @Author  : liuxiangui
# @Date    : 2024/2/3 16:42
# @Describe: 
# ==================================================
import json
import importlib
import os.path
import shutil

import pytest
import sys
from library.run.summary import AllureReportSummary
from library.run.case_status import CaseStatusPackages
from library.notify.larkdriver import LarkChatBot
from library.tools.json_driver import JsonDriver
from library.tools.time import datetime_format_ymd_hms


class BaseRun:
    isLocalRun = False
    reportServerIP = ''
    reportServerPort = 8888
    projectName = ''
    hookLink = ''
    isSendReport = True
    isStartServer = True

    def __init__(self):
        self.currentTime = datetime_format_ymd_hms(days_from_today=0, from_start=3)

    def set_report_title(self):
        """报告suite和标签标题"""
        with open(self.summary_json_file_path, 'r', encoding='utf-8') as file:
            data = json.load(file)
            data["reportName"] = self.projectName
        with open(self.summary_json_file_path, 'w', encoding='utf-8') as file:
            data = json.dumps(data)
            file.write(data)
        # 修改html页签标题
        with open(self.index_html_file_path, 'r', encoding='utf-8') as readFile:
            lines = readFile.readlines()
            for index in range(len(lines)):
                if "<title>" in lines[index]:
                    lines[index] = f"<title>{self.projectName}自动化测试报告</title>\n"
                    break
        with open(self.index_html_file_path, 'w', encoding='utf-8') as writeFile:
            writeFile.write(''.join(lines))

    def history_report_trend(self, filepath: str):
        """报告历史趋势"""
        history_report_path, old_name = self.history_report_path
        if old_name:
            old_path = os.path.join(history_report_path, f"{old_name}/html/{filepath}")
            new_path = os.path.join(self.report_html_path, filepath)
            with open(old_path, 'r', encoding='utf-8') as file:
                data = json.load(file)  # type: list
            with open(new_path, 'r', encoding='utf-8') as fileB:
                data_b = json.load(fileB)
            new_data = data_b + data
            new_data = json.dumps(new_data)
            with open(new_path, 'w', encoding='utf-8') as fileB:
                fileB.write(new_data)
    def optimize_case_allure_parameters(self, filepath: str):
        """清空用例输入参数在标题中展示"""
        curr_path = os.path.join(self.report_html_path, filepath)
        if os.path.isfile(curr_path):
            with open(curr_path, 'r', encoding='utf-8') as fileR:
                data = json.load(fileR)
                JsonDriver.update_all_value_in_json(data, "parameters", [])
            with open(curr_path, 'w', encoding='utf-8') as fileW:
                fileW.write(json.dumps(data))
        else:
            for cur in os.listdir(curr_path):
                new_file_path = os.path.join(curr_path, cur)
                with open(new_file_path, 'r', encoding='utf-8') as fileR:
                    data = json.load(fileR)
                    JsonDriver.update_all_value_in_json(data, "parameters", [])
                with open(new_file_path, 'w', encoding='utf-8') as fileW:
                    fileW.write(json.dumps(data))

    def load_environment_info(self):
        """报告加载环境信息"""
        config_path = importlib.import_module("config").__path__[0]
        env_info_path = os.path.join(config_path, "environment.properties")
        new_info_path = os.path.join(self.report_result_path, "environment.properties")
        shutil.copy(env_info_path, new_info_path)

    @property
    def base_path(self):
        package = importlib.import_module("api")
        common_path = package.__path__[0]
        return os.path.dirname(common_path)

    @property
    def report_result_path(self):
        """报告源文件路径"""
        global current_time_path
        current_time_path = os.path.join(self.report_path, f"{self.projectName}/{self.currentTime}")
        return os.path.join(current_time_path, "allure_result")

    @property
    def report_path(self):
        """报告根路径"""
        return os.path.join(self.base_path, "report")

    @property
    def report_html_path(self):
        """报告生成html路径"""
        return os.path.join(current_time_path, "html")

    @property
    def test_case_path(self):
        """用例路径"""
        return os.path.join(self.base_path, "testcase")

    def start_report_http_server(self):
        """启动报告html服务"""
        if self.isLocalRun:
            start_command = f"allure open {self.report_html_path}"
            os.system(start_command)
        else:
            start_command = f"nohup http-server -p {self.reportServerPort} {self.report_path} >/dev/null 2>&1 &"
            check_server_command = "ps -ef | grep http-server | grep -v grep"
            output = os.popen(check_server_command).read()
            if not output:
                os.popen(start_command).read()

    @property
    def report_link(self):
        """报告访问链接"""
        return f"http://{self.reportServerIP}:{self.reportServerPort}/{self.projectName}/{self.currentTime}/html"

    def start_run(self):
        """执行入口"""
        run_args = sys.argv[1:]
        pytest.main(["-p", "no:warnings", f"--alluredir={self.report_result_path}", "--clean-alluredir"] + run_args)
        self.load_environment_info()
        os.system(f"allure generate {self.report_result_path} -o {self.report_html_path} --clean")

        self.set_report_title()
        self.history_report_trend("widgets/history-trend.json")
        self.history_report_trend("widgets/duration-trend.json")
        self.history_report_trend("widgets/categories-trend.json")
        self.history_report_trend("widgets/retry-trend.json")
        self.optimize_case_allure_parameters("data/behaviors.json")
        self.optimize_case_allure_parameters("data/packages.json")
        self.optimize_case_allure_parameters("data/suites.json")
        self.optimize_case_allure_parameters("data/test-cases")
        if self.isStartServer:
            self.start_report_http_server()
        if self.isSendReport:
            self.send_report()

    def send_report(self):
        """发送报告"""
        summary = AllureReportSummary(self.summary_json_file_path)
        case_stats = CaseStatusPackages(self.packages_json_file_path)
        failed_cases = '\n'.join(case_stats.fail_cases)
        boot = LarkChatBot(self.hookLink, self.report_link, self.projectName)
        boot.post(
            f"  执行时间: {summary.start_time}—{summary.end_time}\n"
            f"  执行耗时: {summary.excute_time}\n"
            f"  用例总数: {summary.case_total_count}\n"
            f"  通过个数: {summary.case_pass_count}\n"
            f"  通  过  率: {summary.case_pass_rate}%\n"
            f"  失败个数: {summary.case_failed_count}\n"
            f"  失败列表: {failed_cases}"
        )

    @property
    def summary_json_file_path(self):
        return os.path.join(self.report_html_path, "widgets/summary.json")

    @property
    def index_html_file_path(self):
        return os.path.join(self.report_html_path, "index.html")

    @property
    def packages_json_file_path(self):
        return os.path.join(self.report_html_path, "data/packages.json")

    @property
    def app_js_file_path(self):
        return os.path.join(self.report_html_path, "app.js")

    @property
    def history_report_path(self):
        """历史报告路径"""
        history_report_path = os.path.join(self.report_path, self.projectName)
        dir_list = os.listdir(history_report_path)
        dir_list.sort()
        old_name = dir_list[-2] if len(dir_list) > 1 else None
        return history_report_path, old_name


if __name__ == '__main__':
    dir_names = os.path.join(BaseRun().report_path, 'study')
    print(dir_names)
    dirlist = os.listdir(dir_names)
    dirlist.sort()
    print(dirlist)
